package vn.sunnet.backviet01.game.coloa.human.enemy;

import org.anddev.andengine.entity.modifier.MoveModifier;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.util.MathUtils;

import vn.sunnet.backviet01.game.coloa.constant.Constants;

public class NhamNgao extends MinisterEnemy {
	private long[] durationMove = { 100, 100, 100, 100, 100, 100, 100 };
	private long[] durationAttack = { 100, 70, 70, 70, 70, 70, 70, 70 };
	private long[] durationDie = { 100, 150, 200, 200, 200, 200, 20, 350, 350,
			100};

	private final TiledTextureRegion mAttack;

	private boolean isDodge = false;
	private boolean isMoveBack = false;

	private long countTimeDodge = 0;
	private long countDodge = 0;

	private long countTimeMoveBack = 0;
	private long timeMoveBack = 0;

	private int countShot = 0;

	private float xBack;
	private float yBack;

	private NhamNgaoStates mState;
	private NhamNgaoStates mLastState;

	public boolean isDie = false;
	public boolean isAllowAttack = false;

	public NhamNgao(int tiledAttack, float pX, float pY,
			TiledTextureRegion pTiledTextureRegion,
			TiledTextureRegion pTiledTextureRegionAttack) {
		super(tiledAttack, pX, pY, pTiledTextureRegion);
		mAttack = pTiledTextureRegionAttack;
		this.name = Constants.NHAMNGAO;
		mState = NhamNgaoStates.MOVE;
		isStun = false;
		isMoveBack = false;
		isDodge = false;
		isAttack = true;

		animate(durationMove, 0, 6, true);
	}

	public void resetInfo() {
		mState = NhamNgaoStates.DIE;
		isDodge = false;
		isMoveBack = false;
		countTimeDodge = 0;
		countShot = 0;
		countDodge = 0;
		isStun = false;
		timeStun = 0;
		isShot = false;
	}

	public void resetStun() {
		if (isStun) {
			timeStun = 0;
			startStun = 0;
			isStun = false;
		}
		
	}
	
	protected void onManagedUpdate(final float pSecondsElapsed) {
		if (isAllowChangeStatus) {
			if (isDie) {
				die();
				isDie = false;
				isAllowChangeStatus = false;
			} else if (mState != NhamNgaoStates.DIE) {
				
				if (mState == NhamNgaoStates.MOVE_BACK && !isMoveBack) {
					moveBack();
					countTimeMoveBack = System.currentTimeMillis();
					isAllowChangeStatus = false;
				} else if (isAllowAttack) {
					attack();
					resetStun();
					countShot = 0;
					isAllowAttack = false;
					isAllowChangeStatus = false;
				} else if (mState == NhamNgaoStates.DODGE && !isDodge) {
					dodge();
					isAllowChangeStatus = false;
				} else if (isStun && startStun == 0) {
					setStunAction();
					isAllowChangeStatus = false;
				}
			}
		} else if (mState != NhamNgaoStates.DIE) {
			if (isMoveBack && this.hitPoints > 0) {
				if (countTimeMoveBack + timeMoveBack < System
						.currentTimeMillis()) {
					move();
					mState = NhamNgaoStates.MOVE;
					isMoveBack = false;
					timeMoveBack = 0;
					countTimeMoveBack = 0;
				}
			} else if (isDodge && !isMoveBack) {
				if (countTimeDodge + countDodge < System.currentTimeMillis()) {
					if (mLastState == NhamNgaoStates.ATTACK) {
						attack();
						mState = NhamNgaoStates.ATTACK;
					} else if (mLastState == NhamNgaoStates.MOVE) {
						move();
						mState = NhamNgaoStates.MOVE;
					}
					isDodge = false;
					countDodge = 0;
					countTimeDodge = 0;
				}
			} else if (isStun && this.hitPoints > 0 && startStun > 0) {
				if (timeStun + startStun < System.currentTimeMillis()) {
					resetStunAction();
				}
			} else if (mState == NhamNgaoStates.ATTACK
					&& this.getCurrentTileIndex() != 0)
				isAttack = false;

			revoverHP();
		} else if (mState == NhamNgaoStates.DIE) {
			if (getCurrentTileIndex() < 7)
				die();
			if (this.life)
				setAlpha(getAlpha() - 0.01f);
		}
		
		super.onManagedUpdate(pSecondsElapsed);
	}

	public void setLastState(NhamNgaoStates pState) {
		this.mLastState = pState;
	}

	public boolean isShot(final float pX, final float pY) {
		if (mState == NhamNgaoStates.DIE)
			return false;
		float x = xContain + getX();
		float y = yContain + getY();

		if ((pX > x && pX < x + widthContain)
				&& (pY > y && pY < y + heightContain) && !isDodge
				&& !isMoveBack) {
			if (mState == NhamNgaoStates.MOVE)
				countShot++;
			return true;
		}

		return false;
	}

	public boolean isDodge() {
		return isDodge;
	}

	public void setStunAction() {
		if (isMoveBack || isDodge) {
			isStun = false;
			return;
		}
		startStun = System.currentTimeMillis();
		switch (mState) {
		case MOVE:
			resetAnimation(150);
			handler.setVelocityX(init_velocity * 0.75f);
			break;
		case ATTACK:
			resetAnimation(100);
			break;

		default:
			break;
		}
	}

	public void resetStunAction() {
		isStun = false;
		startStun = 0;
		timeStun = 0;
		if (mState == NhamNgaoStates.DIE)
			return;

		switch (mState) {
		case MOVE:
			int index = this.getCurrentTileIndex();
			animate(durationMove, 0, 6, true);
			handler.setVelocityX(init_velocity);
			setCurrentTileIndex(index, true);
			break;
		case ATTACK:
			if (getTextureRegion() != mAttack)
				updateTextureRegion(mAttack, true);
			int index1 = this.getCurrentTileIndex();
			animate(durationAttack);
			setCurrentTileIndex(index1, true);
			break;

		default:
			break;
		}
	}

	public long[] resetDuration(long[] duration) {
		int k = duration.length;
		long[] value = new long[k];

		for (int i = 0; i < k; i++) {
			value[i] = (long) (duration[i] * 1.5f);
		}

		return value;
	}

	public void reduceBlood(float blood) {
		super.reduceBlood(blood);
		if (countShot >= 5 && mState != NhamNgaoStates.DIE && !isMoveBack) {
			this.isAllowChangeStatus = true;
			mLastState = mState;
			mState = NhamNgaoStates.DODGE;
			countShot = 0;
		}
	}

	public void updateTexture(TiledTextureRegion pTiledTextureRegion,
			NhamNgaoStates pState) {
		stopAnimation();
		updateTextureRegion(pTiledTextureRegion, true);

		if (pState.getIndex() == 0) {
			widthContain = 70;
			heightContain = 130;
		} else {
			widthContain = 85;
			heightContain = 140;
		}
	}

	public NhamNgaoStates getState() {
		return mState;
	}

	public void setState(NhamNgaoStates pState) {
		mState = pState;
	}

	protected void createContain() {
		xContain = 40;
		yContain = 0;

		widthContain = 70;
		heightContain = 130;
	}

	private void dodge() {
		stopAnimation();
		handler.setEnabled(false);

		if (isStun) {
			isStun = false;
			timeStun = 0;
			startStun = 0;
		}

		float target = MathUtils.random(5, 300);
		float y = getY();
		float time = Math.abs(y - target) / 300;
		countDodge = (long) (time * 1000);

		MoveModifier modifier = new MoveModifier(time, this.getX(),
				this.getX(), y, target);
		registerEntityModifier(modifier);

		countShot = 0;
		countTimeDodge = System.currentTimeMillis();
		isDodge = true;
		mState = NhamNgaoStates.DODGE;
	}

	private void moveBack() {
		if (getTextureRegion() != mTextureRegionMove)
			updateTexture(mTextureRegionMove, NhamNgaoStates.MOVE_BACK);
		stopAnimation(0);
		timeMoveBack = 500;
		MoveModifier modifier = new MoveModifier(0.5f, this.getX(), xBack,
				this.getY(), yBack);
		this.registerEntityModifier(modifier);

		handler.setEnabled(false);
		mState = NhamNgaoStates.MOVE_BACK;
		isMoveBack = true;

	}

	public void moveBack(final float pX, final float pY) {
		if (isDodge || isMoveBack)
			return;
		xBack = pX;
		yBack = pY;
		
		if (xBack > 750)
			xBack = 750;
		mState = NhamNgaoStates.MOVE_BACK;
		isAllowChangeStatus = true;
	}

	public void move() {
		if (getTextureRegion() != mTextureRegionMove)
			updateTexture(mTextureRegionMove, NhamNgaoStates.MOVE);
		this.animate(durationMove, 0, 6, true);
		handler.setEnabled(true);
		handler.setVelocityX(init_velocity);
		mState = NhamNgaoStates.MOVE;
	}

	public void attack() {
		if (getTextureRegion() != mAttack)
			updateTexture(mAttack, NhamNgaoStates.ATTACK);
		setPosition(this.getX()  - 10, this.getY() - 15);
		animate(durationAttack);
		
	}

	public void die() {
		if (getTextureRegion() != mTextureRegionMove) {
			updateTextureRegion(mTextureRegionMove, true);
		}
		if (mLastState == NhamNgaoStates.ATTACK) {
			setPosition(this.getX()  + 10, this.getY() + 15);
		}
		animate(durationDie, 7, 16, false);
		handler.setEnabled(false);
		resetInfo();
	}

	public void setAttackBasic() {
		this.attackBasic = this.streng;
	}

	public static enum NhamNgaoStates {
		MOVE(0), ATTACK(1), DIE(0), MOVE_BACK(0), DODGE(0);

		private final int index;

		NhamNgaoStates(int index) {
			this.index = index;
		}

		public int getIndex() {
			return index;
		}
	}

}
